// ---------------------------------------------------------------------
// archivage.c
// ---------------------------------------------------------------------

#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <mqueue.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <config.h>
#include <simulation.h>
#include <archivage.h>

/* Fait le lien entre le code Thread et le nom du thread */
static const char* CodeVersThread[]={
"Conditionnement",
"Impression",
"Palette",
"Stockage",
"Destockage",
"Lecture",
"Ecriture",
"Archivage",
"Erreur",
"Arrêt Urgence"
};

static const char* CodeVersTexte[]={
"Erreur lors de l'impression",
"La palette est pleine et est envoyée à stockage",
"L'imprimante est Hors Service",
"Trop de pièces défectueuses",
"Absence de palette",
"Stockage de la palette OK",
"Destockage de la palette OK",
"La production est terminée",
"Pas de carton",
"Carton plein",
"Demande d'arret de la chaine de production",
"Commande de produits impossible: stock insuffisant",
"Arrêt de l'application Linux",
"Lancement d'un ordre de fabrication",
"Declenchement de l'arret d'urgence",
"L'impression a été effectuée correctement",
"Absence de pièces en sortie du clapet"
};

int messageOperateur(int typeMessage)
{
	switch (typeMessage)
	{
		// On informe le'opérateur que lorsqu'on stocke ou destocke une palette
		case STOCK_OK : 
			return 1;
		
		case DESTOCK_OK :
			return 1;
			
		case FIN_PRODUCTION :
			return 1;
		
		default :
			return 0;
	}
	return 0;
}


void * Archivage ()
{
	// ---------------------------------------------------------------------
	// Initialisation
	// ---------------------------------------------------------------------

	// Déclaration des variables
	int bytes_read;
	mqd_t queue_handle_versArchivage;
	mqd_t queue_handle_versEcriture;

	// Récupération de BAL_versArchivage
	queue_handle_versArchivage=  mq_open(BAL_versArchivage, O_RDWR);
	if (queue_handle_versArchivage == -1)
	{
		perror ("[ARCHIVAGE] Error Opening MQ BAL_versArchivage:");
	}


	// Récupération de BAL_versEcriture
	queue_handle_versEcriture=  mq_open(BAL_versEcriture, O_RDWR);
	if (queue_handle_versEcriture == -1)
	{
		perror ("[ARCHIVAGE] Error Opening MQ BAL_versEcriture:");
	}
	
	/* Creation et Ouverture journal de log pour le jour */
	/* ----- récuperation de la date du jour */
	time_t temps;
	struct tm * t;
	char date[21];
	temps = time(NULL);
	t = localtime(&temps);
	strftime(date,21,"journal_%d_%m_%y.txt",t);
	printf("nom %s \n", date);
	/* ----- ouverture du fichier */
	FILE *journal = fopen(date,"a+");
	if(journal == NULL)
	{
		printf("Erreur : impossible de créer le journal\n");
	}

	// ---------------------------------------------------------------------
	// Moteur
	// ---------------------------------------------------------------------

	for (; ;)
	{ 
		// Attente du dépot d'un message d'erreur dans la boite aux lettres
		MSG_versArchivage messageVersArchivage;
		bytes_read = mq_receive(queue_handle_versArchivage, (char*) &messageVersArchivage, sizeof(MSG_versArchivage), NULL);

		if (bytes_read == -1)
		{
			perror("[ARCHIVAGE] Failed to recieve BAL_versErreur:");
		}
		else
		{			
			// -----------------------------------
			// On récupère la structure du message 
			// -----------------------------------
			int archiSource = messageVersArchivage.source;
			int archiMessage = messageVersArchivage.message;
			time_t archiHeure = messageVersArchivage.heure;
			int archiNumLot = messageVersArchivage.numLot;
			int archiCartonEnCours = messageVersArchivage.cartonEnCours;
			int archiType = messageVersArchivage.type;

			
			
			// -----------------------------------
			// On écrit dans le fichier
			// -----------------------------------
			t = localtime(&archiHeure);
			char messageLog[1000];
			strftime(messageLog,100,"%d/%m/%y à %H:%M:%S : ",t);	
			
			if (archiType == ERREUR)
			{
				strcat(messageLog,"[ERREUR] ");
			}
			else
			{
				strcat(messageLog,"[ARCHIVAGE] ");
			}
			
			strcat(messageLog, CodeVersThread[archiSource]); 
			
			strcat(messageLog," : \"");
			strcat(messageLog, CodeVersTexte[archiMessage]); 
			
			strcat(messageLog, "\" - Numéro du lot ");
			char numLotChar[100];
			sprintf(numLotChar, "%d", archiNumLot);
			strcat(messageLog, numLotChar);
			
			strcat(messageLog, " - Numéro du carton en cours ");
			char cartonEnCoursChar[100];
			sprintf(cartonEnCoursChar, "%d", archiCartonEnCours);
			strcat(messageLog, cartonEnCoursChar);
			strcat(messageLog, "\n");
			
			fprintf(journal, "%s",messageLog);
			// -----------------------------------
			// On teste si le message doit être 
			// transmis à l'opérateur
			// -----------------------------------
			if (archiType == ARCHIVAGE)
			{
				// Le message doit être transmis
				
				// Création du message
				MSG_versEcriture messageVersEcriture;
				messageVersEcriture.typeMessage = archiType;
				messageVersEcriture.message = archiMessage;
				messageVersEcriture.heure = archiHeure;
				messageVersEcriture.numLot = archiNumLot;
				messageVersEcriture.cartonEnCours = archiCartonEnCours;


				// Envoie du message pour Archivage
				if (0 != mq_send (queue_handle_versEcriture, (const char*) &messageVersEcriture, sizeof(MSG_versEcriture), PRIO_MSG_L))
				{
					perror ("[ARCHIVAGE] Sending to BAL_versEcriture:");
				}
				
			}
			
			// -----------------------------------
			// On teste si le message demande
			// la fin de l'activité
			// -----------------------------------
			if (archiMessage == CLOSE_APPLI)
			{
				// Il faut terminer l'activité
				
				// On ferme les boites au lettres
				mq_close(queue_handle_versArchivage);
				mq_close(queue_handle_versEcriture);
				
				// On finit la tâche en cours
				/* Fermeture du journal de log */
				fclose(journal);
				
				// On se suicide
				pthread_exit(0);
			}
		}  
	}
	fclose(journal);
}


